package Tools;
import Appconst.GameConst;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;

public  class Animation {
//	 public static final int SPX_HEADER = 1397772888; // DFSPX
//
//	    // sprite class version
//	    public static final byte SPX_VERSION = 34; // 3.4
//	    //
//	    // // byte sequence
//	    public static final byte SPX_BYTE_SEQUENCE_JAVA = 1;

	    // public static final int SPX_BYTE_SEQUENCE_C = 0;
	
		public static  int screen_w = 0;
		public static  int screen_h = 0;
	    // sprite transform type
	    public static final byte TRANS_NONE = 0;
	    public static final byte TRANS_ROT90 = 5;
	    public static final byte TRANS_ROT180 = 3;
	    public static final byte TRANS_ROT270 = 6;
	    public static final byte TRANS_MIRROR = 2;
	    public static final byte TRANS_MIRROR_ROT90 = 7;
	    public static final byte TRANS_MIRROR_ROT180 = 1;
	    public static final byte TRANS_MIRROR_ROT270 = 4;

	    // rotate bit
	    public static final byte ANTICLOCKWISE_90 = 0;
	    public static final byte DEASIL_90 = 1;
	    public static final byte HORIZONTAL = 2;
	    public static final byte VERTICAL = 3;

	    // sprite direction
	    public static final byte DIRECTION_NONE = 0;
	    public static final byte DIRECTION_UP = 1;
	    public static final byte DIRECTION_DOWN = 2;
	    public static final byte DIRECTION_LEFT = 3;
	    public static final byte DIRECTION_RIGHT = 4;

	    // frame attrib
	    public static final byte FRAME_HEADER_SIZE = 8;

	    // frame data bit
	    public static final byte FRAME_TILE_COUNT_BIT = 1;
	    public static final byte FRAME_COLLISION_COUNT_BIT = 2;
	    public static final byte FRAME_REFERENCE_POINT_COUNT_BIT = 3;
	    public static final byte FRAME_TOP_POS_BIT = 4;
	    public static final byte FRAME_BOTTOM_POS_BIT = 5;
	    public static final byte FRAME_LEFT_POS_BIT = 6;
	    public static final byte FRAME_RIGHT_POS_BIT = 7;

	    // action attrib
	    public static final byte ACTION_HEADER_SIZE = 4;

	    // action data bit
	    public static final byte ACTION_SEQUENCE_LENGTH_BIT = 1;
	    public static final byte ACTION_SEQUENCE_DELAY_BIT = 2;
	    public static final byte ACTION_TRANSFORM_BIT = 3;

	    // collision type
	    public static final byte COLLISION_INTERSECT = 1;
	    public static final byte COLLISION_INCLUSION = 2;
	    public static final byte INVERTED_AXES = 0x4;

	    
	    public static final int SOLID = 0;
		public static final int DOTTED = 1;
		public static final int LEFT = 4;
		public static final int RIGHT = 8;
		public static final int TOP = 16;
		public static final int BASELINE = 64;
		public static final int BOTTOM = 32;
		public static final int HCENTER = 1;
		public static final int VCENTER = 2;
	    private AnimationListener listener;
	    // transfrom table
	    public static final byte[][] TRANSFORM_TABLE = new byte[ /* 8 */][ /* 8 */] {
	            { TRANS_NONE, TRANS_MIRROR_ROT180, TRANS_MIRROR, TRANS_ROT180,
	                    TRANS_MIRROR_ROT270, TRANS_ROT90, TRANS_ROT270,
	                    TRANS_MIRROR_ROT90 },
	            { TRANS_MIRROR_ROT180, TRANS_NONE, TRANS_ROT180, TRANS_MIRROR,
	                    TRANS_ROT90, TRANS_MIRROR_ROT270, TRANS_MIRROR_ROT90,
	                    TRANS_ROT270 },
	            { TRANS_MIRROR, TRANS_ROT180, TRANS_NONE, TRANS_MIRROR_ROT180,
	                    TRANS_ROT270, TRANS_MIRROR_ROT90, TRANS_MIRROR_ROT270,
	                    TRANS_ROT90 },
	            { TRANS_ROT180, TRANS_MIRROR, TRANS_MIRROR_ROT180, TRANS_NONE,
	                    TRANS_MIRROR_ROT90, TRANS_ROT270, TRANS_ROT90,
	                    TRANS_MIRROR_ROT270 },
	            { TRANS_MIRROR_ROT270, TRANS_ROT270, TRANS_ROT90,
	                    TRANS_MIRROR_ROT90, TRANS_NONE, TRANS_MIRROR,
	                    TRANS_MIRROR_ROT180, TRANS_ROT180 },
	            { TRANS_ROT90, TRANS_MIRROR_ROT90, TRANS_MIRROR_ROT270,
	                    TRANS_ROT270, TRANS_MIRROR_ROT180, TRANS_ROT180,
	                    TRANS_NONE, TRANS_MIRROR },
	            { TRANS_ROT270, TRANS_MIRROR_ROT270, TRANS_MIRROR_ROT90,
	                    TRANS_ROT90, TRANS_MIRROR, TRANS_NONE, TRANS_ROT180,
	                    TRANS_MIRROR_ROT180 },
	            { TRANS_MIRROR_ROT90, TRANS_ROT90, TRANS_ROT270,
	                    TRANS_MIRROR_ROT270, TRANS_ROT180, TRANS_MIRROR_ROT180,
	                    TRANS_MIRROR, TRANS_NONE } };

	    // rotate table
	    public static final byte ROTATE_TABLE[][] = new byte[ /* 8 */][ /* 4 */] {
	            { TRANS_ROT270, TRANS_ROT90, TRANS_MIRROR, TRANS_MIRROR_ROT180 },
	            { TRANS_MIRROR_ROT90, TRANS_MIRROR_ROT270, TRANS_ROT180, TRANS_NONE },
	            { TRANS_MIRROR_ROT270, TRANS_MIRROR_ROT90, TRANS_NONE, TRANS_ROT180 },
	            { TRANS_ROT90, TRANS_ROT270, TRANS_MIRROR_ROT180, TRANS_MIRROR },
	            { TRANS_MIRROR_ROT180, TRANS_MIRROR, TRANS_ROT90, TRANS_ROT270 },
	            { TRANS_NONE, TRANS_ROT180, TRANS_MIRROR_ROT270, TRANS_MIRROR_ROT90 },
	            { TRANS_ROT180, TRANS_NONE, TRANS_MIRROR_ROT90, TRANS_MIRROR_ROT270 },
	            { TRANS_MIRROR, TRANS_MIRROR_ROT180, TRANS_ROT270, TRANS_ROT90 } };



	    
	    
	    
	  
	    int actionIndex; // current action
	    int sequenceIndex; // current action sequence
	    
	    
	    Bitmap image; // sprite image
	    
	    short tileCount; // tile count
	    Bitmap[] tiles;
	    boolean tileMode;
	    short[][] tileData; // tile data
	    short frameCount; // frame count
	    short[][] frameData; // frame data
	    byte actionCount; // action count
	    short[][] actionData; // action data
	    
	    
	    int x; // sprite x position
	    int y; // sprite y position
	    boolean visible; // sprite visible
	    long lastTime; // last update sequence time
	    boolean firstUpdate; // frist update sequence
	    boolean disableUpdate; // disable update sequence

	    // origin offset position
	    int originOffsetX;
	    int originOffsetY;
	    
	    public Animation(AnimationData data){
	    	this.image = data.image;
	    	this.tileCount = data.tileCount;
	    	this.tiles = data.tiles;
	    	this.tileMode = data.tileMode;
	    	this.tileData = data.tileData;
	    	this.frameCount = data.frameCount;
	    	this.frameData = data.frameData;
	    	this.actionCount = data.actionCount;
	    	this.actionData = data.actionData;
	    	
	    	screen_w = GameConst.SCR_W;
	    	screen_h = GameConst.SCR_H;
	    	visible = true;
	    }
	    
//	    public SpriteX(SpriteX spx) {
//	        // init vars
//	        int i, length;
//	        actionCount = spx.actionCount;
//	        frameCount = spx.frameCount;
//	        tileCount = spx.tileCount;
//	        actionData = new short[actionCount][];
//	        frameData = new short[frameCount][];
//	        tileData = new short[tileCount][];
//	        // copy action
//	        for (i = 0; i < actionCount; i++) {
//	            length = spx.actionData[i][0];
//	            actionData[i] = new short[length];
//	            System.arraycopy(spx.actionData[i], 0, actionData[i], 0, length);
//	        }
//	        // copy frame
//	        for (i = 0; i < frameCount; i++) {
//	            length = spx.frameData[i][0];
//	            frameData[i] = new short[length];
//	            System.arraycopy(spx.frameData[i], 0, frameData[i], 0, length);
//	        }
//	        // copy tile
//	        for (i = 0; i < tileCount; i++) {
//	            length = 4;
//	            tileData[i] = new short[length];
//	            System.arraycopy(spx.tileData[i], 0, tileData[i], 0, length);
//	        }
//	        // copy data
//	        actionIndex = spx.actionIndex;
//	        sequenceIndex = spx.sequenceIndex;
//	        image = spx.image;
//	        x = spx.x;
//	        y = spx.y;
//	        visible = spx.visible;
//	        lastTime = spx.lastTime;
//	        firstUpdate = spx.firstUpdate;
//	        disableUpdate = spx.disableUpdate;
//	    }

	    public void enableUpdate(boolean enable) {
	        if (disableUpdate && enable) {
	            lastTime = System.currentTimeMillis();
	        }
	        disableUpdate = !enable;
	    }

	    public boolean isEnableUpdate() {
	        return !disableUpdate;
	    }

	    public void setImage(Bitmap image) {
	        // if (image == null) {
	        // throw new NullPointerException();
	        // }
	        // else {
	        this.image = image;
	        // }
	    }

	    public Bitmap getImage() {
	        return image;
	    }

	    public Bitmap getImage(int index) {
	        return tiles[index];
	    }

	    public void setPosition(int x, int y) {
	        this.x = x;
	        this.y = y;
	    }

	    public void move(int dx, int dy) {
	        x += dx;
	        y += dy;
	    }

	    public final int getX() {
	        return x;
	    }

	    public final int getY() {
	        return y;
	    }

	    public void setVisible(boolean visible) {
	        this.visible = visible;
	    }

	    public boolean isVisible() {
	        return visible;
	    }

	    public void setX(int x) {
	        this.x = x;
	    }

	    public void setY(int y) {
	        this.y = y;
	    }
	    public int getAction() {
	        return actionIndex;
	    }

	    public int getActionCount() {
	        return actionCount;
	    }

	    public void setFrame(int sequenceIndex) {
	        if (sequenceIndex < 0 || sequenceIndex >= getSequenceLength()) {
	            throw new IndexOutOfBoundsException();
	        } else {
	            this.sequenceIndex = sequenceIndex;
	            this.firstUpdate = false;
	        }
	    }

	    public int getFrame() {
	        return sequenceIndex;
	    }

	    public void setTransform(byte transform) {
	        if (transform < 0 || transform > 7) {
	            throw new IllegalArgumentException();
	        } else {
	            actionData[actionIndex][ACTION_TRANSFORM_BIT] = transform;
	        }
	    }

	    public int getTransform() {
	        return actionData[actionIndex][ACTION_TRANSFORM_BIT];
	    }

	    public void deasilRotate90() {
	        setTransform(ROTATE_TABLE[getTransform()][DEASIL_90]);
	    }

	    void anticlockwiseRotate90() {
	        setTransform(ROTATE_TABLE[getTransform()][ANTICLOCKWISE_90]);
	    }

	    void horizontalMirror() {
	        setTransform(ROTATE_TABLE[getTransform()][HORIZONTAL]);
	    }

	    void verticalMirror() {
	        setTransform(ROTATE_TABLE[getTransform()][VERTICAL]);
	    }

	    public void nextFrame() {
	    	if(sequenceIndex == (getSequenceLength() - 1)){
	    		sequenceIndex = 0;
		    	} else {
		    		sequenceIndex++;
		    	}
//	        sequenceIndex = ((sequenceIndex + 1) % getSequenceLength());
	        firstUpdate = false;
	    }

	    public void prevFrame() {
	        if (sequenceIndex == 0) {
	            sequenceIndex = getSequenceLength() - 1;
	        } else {
	            sequenceIndex--;
	        }
	        firstUpdate = false;
	    }

//		public void update(long time) {
//			if (!isEnableUpdate()) {
//				return;
//			}
//			if (isDelay()) {
//				if (!firstUpdate) {
//					firstUpdate = true;
//					this.lastTime = time;
//				}
//				int dms = getDelayTime();
//				if ((time - this.lastTime) >= dms) {
//					nextFrame();
//					this.lastTime = time;
//				}
//			}
//		}
	    /**
	     * 当前动作的循环次数
	     */
	    public int loopNum;
	    public int nextAction = -1;
	    /**
	     * 设置动作，以及循环次数
	     * @param actionIndex 动作索引
	     * @param loopNum 循环次数 -1为无限循环 0为停止 1为循环1次 >1 为循环的loopNum次数
	     */
	    public void setAction(int actionIndex , int loopNum){
			if (actionIndex < 0 || actionIndex >= actionCount) {
				throw new IndexOutOfBoundsException();
			}
			else {
				this.actionIndex = actionIndex;
				this.sequenceIndex = 0;
				this.firstUpdate = false;
			}
	        this.loopNum = loopNum;
	    }
	    public void setAction(int actionIndex , int loopNum,int nextAction){
			if (actionIndex < 0 || actionIndex >= actionCount) {
				throw new IndexOutOfBoundsException();
			}
			else {
				this.actionIndex = actionIndex;
				this.sequenceIndex = 0;
				this.firstUpdate = false;
			}
	        this.loopNum = loopNum;
	        this.nextAction = nextAction;
	    }
		/**
		 * 设置动作(对应spriteX的动作顺序)
		 *
		 * @param actionIndex
		 *            动作编号
		 */
		public void setAction(int actionIndex) {
			setAction(actionIndex,-1);
		}
	    /**
	     * 设置循环次数
	     * @param loopNum
	     */
	    public void setLoopNum(int loopNum){
	        this.loopNum = loopNum;
	    }
	    /**
	     *
	     * @return返回循环次数
	     */
	    public int getLoopNum(){
	    	return loopNum;
	    }
	    /**
	     * 没有设置延迟时间的 update
	     */
//	    public void updateNodelay(){
//	    	if(loopNum == 0){
//	        	return;
//	        }
//	    	switch (loopNum) {
//			case -1://无线循环状态
//				nextFrame();
//				break;
//			case 0://循环一次之后切换到此状态
//				
//				break;
//			case 1://循环一次
//				if(sequenceIndex == getSequenceLength() - 1){
//					this.setLoopNum(0);
//					return;
//				}
//				nextFrame();
//				break;
//			default://循环n次
//				if(sequenceIndex == getSequenceLength() - 1){
//    				loopNum--;
//    				if(loopNum == 1){
//    					sequenceIndex = 0;
//    					return;
//    				}
//    			}
//				nextFrame();
//				break;
//			}
//	    }
	    /**
	     * isVisible 只对循环n次有效 n可以为1 如果想让循环n次的动作 可以切换到其他动作 参数要设置为true
	     */
	    public void update(boolean isVisible) {
	    	if (!isEnableUpdate()) {
	    		return;
	    	}
	    	if(loopNum == 0){
	    		return;
	    	}
	    	if (isDelay()) {
	    		long time = System.currentTimeMillis();
	    		switch(loopNum){
	    		case -1: //无线循环状态
	    		if (!firstUpdate) {
	    			firstUpdate = true;
	    			this.lastTime = time;
	    		}
	    		int dms = getDelayTime();
	    		if ((time - this.lastTime) >= dms) {
	    			nextFrame();
	    			this.lastTime = time;
	    		}
	    		break;
	    		case 0://循环一次之后切换到此状态

	    			break;
	    		case 1://循环一次
	    			if (!firstUpdate) {
	    				firstUpdate = true;
	    				this.lastTime = time;
	    			}
	    			int dms1 = getDelayTime();
	    			if ((time - this.lastTime) >= dms1) {
	    				System.out.println("sequenceIndex ="+sequenceIndex);
	    				if(sequenceIndex == getSequenceLength() - 1){
	    					this.visible = isVisible;
	    					this.setLoopNum(0);
	    					//====================
//	    					if(nextAction != -1&&nextAction>=0&&nextAction<getActionCount())
//	    					{
//	    						setAction(nextAction);
//	    						nextAction = -1;
//	    					}
//	    					else
//	    					{
	    					listener.endofAnimation(this);
//	    					}
	    					//====================
	    					
	    					//sequenceIndex = getSequenceLength() - 1;
	    					return;
	    				}
	    				if (sequenceIndex < getSequenceLength() - 1) {
	    					sequenceIndex++;
	    					firstUpdate = false;
	    				}
	    				this.lastTime = time;
	    			}
	    			break;
	    		default://循环n次
	    			if (!firstUpdate) {
	    				firstUpdate = true;
	    				this.lastTime = time;
	    			}
	    			int dms2 = getDelayTime();
	    			if ((time - this.lastTime) >= dms2) {
	    				sequenceIndex = ((sequenceIndex + 1) % getSequenceLength());
	    				firstUpdate = false;
	    				if(sequenceIndex == getSequenceLength() - 1){
	    					loopNum--;
	    					if(loopNum == 1){
	    						sequenceIndex = 0;
	    					}
	    				}
	    				this.lastTime = time;
	    			}
	    			break;
	    		}

	    	} else {
	    		switch (loopNum) {
	    		case -1://无线循环状态
	    			nextFrame();
	    			break;
	    		case 0://循环一次之后切换到此状态

	    			break;
	    		case 1://循环一次
	    			if(sequenceIndex == getSequenceLength() - 1){
	    				this.setLoopNum(0);
	    				this.visible = isVisible;
	    				return;
	    			}
	    			nextFrame();
	    			break;
	    		default://循环n次
	    			if(sequenceIndex == getSequenceLength() - 1){
	    				loopNum--;
	    				if(loopNum == 1){
	    					sequenceIndex = 0;
	    					return;
	    				}
	    			}
	    			nextFrame();
	    			break;
	    		}
	    	}
	    }

	    public int getSequenceFrame(int sequenceIndex) {
	        if (isDelay()) {
	            return actionData[actionIndex][ACTION_HEADER_SIZE + sequenceIndex
	                    * 2];
	        } else {
	            return actionData[actionIndex][ACTION_HEADER_SIZE + sequenceIndex];
	        }
	    }

	    public int getSequenceFrame() {
	        if (isDelay()) {
	            return actionData[actionIndex][ACTION_HEADER_SIZE + sequenceIndex
	                    * 2];
	        } else {
	            return actionData[actionIndex][ACTION_HEADER_SIZE + sequenceIndex];
	        }
	    }

	    public int getSequenceLength() {
	        return actionData[actionIndex][ACTION_SEQUENCE_LENGTH_BIT];
	    }

	    public boolean isDelay() {
	        if (actionData[actionIndex][ACTION_SEQUENCE_DELAY_BIT] == 1) {
	            return true;
	        } else {
	            return false;
	        }
	    }
	    //jnmo 设置delayTime
	    private float delayTimeP =  1.0f;
	    /**
	     * 设置播放速率1为正常速率2为延长2倍 
	     * @param delayTimeP
	     */
	    public void setDelayTimeP(float delayTimeP)
	    {
	    	this.delayTimeP = delayTimeP; 
	    }
	    public int getDelayTime() {
	        return (int)(actionData[actionIndex][ACTION_HEADER_SIZE + sequenceIndex * 2
	                + 1] * delayTimeP);
	    }
	    
	    public int getReferencePointX(int index) {
	        int frameIndex = getSequenceFrame();
	        int frameTileCount = frameData[frameIndex][FRAME_TILE_COUNT_BIT];
	        int frameCollisionCount = frameData[frameIndex][FRAME_COLLISION_COUNT_BIT];
	        int offset = FRAME_HEADER_SIZE + frameTileCount * 4
	                + frameCollisionCount * 4 + index * 2;
	        int refX = frameData[frameIndex][offset];
	        int refY = frameData[frameIndex][offset + 1];
	        return getTransformedReferenceX(refX, refY, getTransform()) + x;
	    }

	    public int getReferencePointY(int index) {
	        int frameIndex = getSequenceFrame();
	        int frameTileCount = frameData[frameIndex][FRAME_TILE_COUNT_BIT];
	        int frameCollisionCount = frameData[frameIndex][FRAME_COLLISION_COUNT_BIT];
	        int offset = FRAME_HEADER_SIZE + frameTileCount * 4
	                + frameCollisionCount * 4 + index * 2;
	        int refX = frameData[frameIndex][offset];
	        int refY = frameData[frameIndex][offset + 1];
	        return getTransformedReferenceY(refX, refY, getTransform()) + y;
	    }

	    public int getReferencePointCount(int frameIndex) {
	        if (frameIndex < 0 && frameIndex >= frameCount) {
	            throw new ArrayIndexOutOfBoundsException();
	        }
	        int frameReferencePointCount = frameData[frameIndex][FRAME_REFERENCE_POINT_COUNT_BIT];
	        return frameReferencePointCount;
	    }

	    public int getReferencePointCount() {
	        int frameIndex = getSequenceFrame();
	        return getReferencePointCount(frameIndex);
	    }

	    int getTransformedReferenceX(int x, int y, int transform) {
	        int t_x = 0;
	        switch (transform) {
	        case TRANS_NONE:
	            t_x = x;
	            break;
	        case TRANS_MIRROR:
	            t_x = -x;
	            break;
	        // case TRANS_MIRROR_ROT180:
	        // t_x = x;
	        // break;
	        // case TRANS_ROT90:
	        // t_x = srcFrameHeight - y - 1;
	        // break;
	        // case TRANS_ROT180:
	        // t_x = srcFrameWidth - x - 1;
	        // break;
	        // case TRANS_ROT270:
	        // t_x = y;
	        // break;
	        // case TRANS_MIRROR_ROT90:
	        // t_x = srcFrameHeight - y - 1;
	        // break;
	        // case TRANS_MIRROR_ROT270:
	        // t_x = y;
	        // break;
	        }
	        return t_x;
	    }

	    int getTransformedReferenceY(int x, int y, int transform) {
	        int t_y = 0;
	        switch (transform) {
	        case TRANS_NONE:
	            t_y = y;
	            break;
	        case TRANS_MIRROR:
	            t_y = y;
	            break;
	        // case TRANS_MIRROR_ROT180:
	        // t_y = srcFrameHeight - y - 1;
	        // break;
	        // case TRANS_ROT90:
	        // t_y = x;
	        // break;
	        // case TRANS_ROT180:
	        // t_y = srcFrameHeight - y - 1;
	        // break;
	        // case TRANS_ROT270:
	        // t_y = srcFrameWidth - x - 1;
	        // break;
	        // case TRANS_MIRROR_ROT90:
	        // t_y = srcFrameWidth - x - 1;
	        // break;
	        // case TRANS_MIRROR_ROT270:
	        // t_y = x;
	        // break;
	        }
	        return t_y;
	    }

	    public int getCollidesX(int frame, int index) {
	        if (index < 0 || index >= frameData[frame][FRAME_COLLISION_COUNT_BIT]) {
	            throw new ArrayIndexOutOfBoundsException();
	        } else {
	            int offset = FRAME_HEADER_SIZE
	                    + frameData[frame][FRAME_TILE_COUNT_BIT] * 4 + index * 4;

	            return frameData[frame][offset] + x;
	        }
	    }

	    public int getCollidesY(int frame, int index) {
	        if (index < 0 || index >= frameData[frame][FRAME_COLLISION_COUNT_BIT]) {
	            throw new ArrayIndexOutOfBoundsException();
	        } else {
	            int offset = FRAME_HEADER_SIZE
	                    + frameData[frame][FRAME_TILE_COUNT_BIT] * 4 + index * 4
	                    + 1;

	            return frameData[frame][offset] + y;
	        }
	    }

	    public int getCollidesWidth(int frame, int index) {
	        if (index < 0 || index >= frameData[frame][FRAME_COLLISION_COUNT_BIT]) {
	            throw new ArrayIndexOutOfBoundsException();
	        } else {
	            int offset = FRAME_HEADER_SIZE
	                    + frameData[frame][FRAME_TILE_COUNT_BIT] * 4 + index * 4
	                    + 2;

	            return frameData[frame][offset];
	        }
	    }

	    public int getCollidesHeight(int frame, int index) {
	        if (index < 0 || index >= frameData[frame][FRAME_COLLISION_COUNT_BIT]) {
	            throw new ArrayIndexOutOfBoundsException();
	        } else {
	            int offset = FRAME_HEADER_SIZE
	                    + frameData[frame][FRAME_TILE_COUNT_BIT] * 4 + index * 4
	                    + 3;

	            return frameData[frame][offset];
	        }
	    }

	    public int getCollidesX(int index) {
	        int frameIndex = getSequenceFrame();
	        return getCollidesX(frameIndex, index);
	    	
	    }

	    public int getCollidesY(int index) {
	        int frameIndex = getSequenceFrame();
	        return getCollidesY(frameIndex, index);
	    }

	    public int getCollidesWidth(int index) {
	        int frameIndex = getSequenceFrame();
	        return getCollidesWidth(frameIndex, index);
	    }

	    public int getCollidesHeight(int index) {
	        int frameIndex = getSequenceFrame();
	        return getCollidesHeight(frameIndex, index);
	    }

	    public int getCollidesCount(int index) {
	        return frameData[index][FRAME_COLLISION_COUNT_BIT];
	    }

	    public int getCollidesCount() {
	        return frameData[getSequenceFrame()][FRAME_COLLISION_COUNT_BIT];
	    }
	    public boolean collidesWith(Animation animation, int id1, int id2) {
	        if (!animation.visible || !this.visible) {
	            return false;
	        }
	        if (this.getCollidesCount() == 0 || animation.getCollidesCount() == 0) {
	            return false;
	        }
	        if (id1 >= this.getCollidesCount() || id2 >= animation.getCollidesCount()) {
	            return false;
	        }
	        return collidesWith(animation, id2, id1, COLLISION_INTERSECT);
	    }

	    public boolean collidesWith(Animation animation, int spxCollides, int thisCollides,
	            int type) {
	        if (!animation.visible || !this.visible) {
	            return false;
	        }
	        int x = animation.getCollidesX(spxCollides);
	        int y = animation.getCollidesY(spxCollides);
	        int width = animation.getCollidesWidth(spxCollides);
	        int height = animation.getCollidesHeight(spxCollides);

	        // System.out.println("x:"+x);
	        // System.out.println("y:"+y);
	        // System.out.println("width:"+width);
	        // System.out.println("height:"+height);
	        return collidesWith(x, y, width, height, thisCollides, type);
	    }

	    public boolean collidesWith(Bitmap image, int x, int y, int collides,
	            int type) {
	        return collidesWith(x, y, image.getWidth(), image.getHeight(),
	                collides, type);
	    }

	    public boolean collidesWith(int x, int y, int width, int height,
	            int collides, int type) {
	        if (!this.visible) {
	            return false;
	        }

	        int x1 = this.getCollidesX(collides);
	        int y1 = this.getCollidesY(collides);
	        int w1 = this.getCollidesWidth(collides);
	        int h1 = this.getCollidesHeight(collides);
	        // System.out.println("x1:"+x1);
	        // System.out.println("y1:"+y1);
	        // System.out.println("width1:"+w1);
	        // System.out.println("height1:"+h1);
	        if (type == COLLISION_INTERSECT) {
	            return intersectRect(x1, y1, w1, h1, x, y, width, height);
	        } else if (type == COLLISION_INCLUSION) {
	            return inclusionRect(x1, y1, w1, h1, x, y, width, height);
	        } else {
	            throw new ArithmeticException();
	        }
	    }
	    public int mycollidesWith(int x, int y, int width, int height,
	            int type) {
	        if (!this.visible) {
	            return -1;
	        }
	        System.out.println("getCollidesCount = "+getCollidesCount());
	        for (int i = 0; i < getCollidesCount(); i++) {
				if(collidesWith(x, y, width, height, i, type))
				{
					return i;
				}
			}
	        return -1;
	        
	    }

	    public boolean collidesWith(Animation animation) {
	        if (!animation.visible || !this.visible) {
	            return false;
	        }
	        if (this.getCollidesCount() == 0 || animation.getCollidesCount() == 0) {
	            return false;
	        }
	        return collidesWith(animation, 0, 0, COLLISION_INTERSECT);
	    }

	    public boolean collidesWith(Bitmap image, int x, int y) {
	        if (!this.visible) {
	            return false;
	        }
	        if (this.getCollidesCount() == 0) {
	            return false;
	        }
	        return collidesWith(image, x, y, 0, COLLISION_INTERSECT);
	    }

	    public boolean collidesWith(int x, int y, int width, int height) {
	        if (!this.visible) {
	            return false;
	        }
	        if (this.getCollidesCount() == 0) {
	            return false;
	        }
	        return collidesWith(x, y, width, height, 0, COLLISION_INTERSECT);
	    }

	    public static boolean intersectRect(int x1, int y1, int width1,
	            int height1, int x2, int y2, int width2, int height2) {
	        if (y2 + height2 < y1 || y2 > y1 + height1 || x2 + width2 < x1
	                || x2 > x1 + width1) {
	            return false;
	        } else {
	            return true;
	        }
	    }

	    public static boolean inclusionRect(int x1, int y1, int width1,
	            int height1, int x2, int y2, int width2, int height2) {
	        if (y2 >= y1 && y2 + height2 <= y1 + height1 && x2 >= x1
	                && x2 + width2 <= x1 + width1) {
	            return true;
	        }

	        return false;
	    }

	    public void originOffset(int x, int y) {
	        originOffsetX = x;
	        originOffsetY = y;
	    }

	    public int getFrameTopPos() {
	        return frameData[getSequenceFrame()][FRAME_TOP_POS_BIT] + y;
	    }
	    public int getFrameBottomPos() {
	        return frameData[getSequenceFrame()][FRAME_BOTTOM_POS_BIT] + y;
	    }

	    public int getFrameLeftPos() {
	        return frameData[getSequenceFrame()][FRAME_LEFT_POS_BIT] + x;
	    }
	    public int getFrameRightPos() {
	        return frameData[getSequenceFrame()][FRAME_RIGHT_POS_BIT] + x;
	    }

	    public int getFrameWidth() {
	        return getFrameRightPos() - getFrameLeftPos();
	    }

	    public int getFrameHeight() {
	        return getFrameBottomPos() - getFrameTopPos();
	    }
	    public boolean isOver(){
	    	if(!visible){
	    		return false;
	    	}
	    	if(getFrame() == getSequenceLength()-1){
		    	return true;
		    }
	    	return false;
	    }
	    
//	    public void paint(Graphics g) {
//	        paint(g, x, y);
//	    }

	    public void paint(Canvas canvas,Paint paint,int x, int y) {
//	        if (g == null) {
//	            throw new NullPointerException();
//	        }
	        if (visible) {
	            x -= originOffsetX;
	            y -= originOffsetY;
//jnmo
	            
	            int clipX = 0/*g.getClipX()*/;
	            int clipY = 0/*g.getClipY()*/;
	            int clipWidth = screen_w/*g.getClipWidth()*/;
				int clipHeight = screen_h/*g.getClipHeight()*/;
	            
//	            System.out.println("clipX:"+clipX);
//	            System.out.println("clipY:"+clipY);
//	            System.out.println("clipWidth:"+clipWidth);
//	            System.out.println("clipHeight:"+clipHeight);
	            int actionTransform = getTransform();
	            if (actionTransform == TRANS_NONE) {
	                int tileIndex; // tile index
	                int dx; // tile dest x
	                int dy; // tile dest y
	                int transform; // tile transform
	                int tx; // tile x
	                int ty; // tile y
	                int tw; // tile width
	                int th; // tile height
	                int frameIndex = getSequenceFrame();
	                int tileCount = frameData[frameIndex][FRAME_TILE_COUNT_BIT];
	                int offset = FRAME_HEADER_SIZE; // tile data offset
	                for (int i = 0; i < tileCount; i++) {
	                    if (tileMode) {
	                        tileIndex = frameData[frameIndex][0 + offset];
	                        dx = frameData[frameIndex][1 + offset] + x;
	                        dy = frameData[frameIndex][2 + offset] + y;              
	                        transform = frameData[frameIndex][3 + offset];
	                        tx = 0;
	                        ty = 0;
	                        tw = tiles[tileIndex].getWidth();
	                        th = tiles[tileIndex].getHeight();

	                        if (intersectRect(dx, dy, tw, th, clipX, clipY,
	                                clipWidth, clipHeight)) {
	                            drawRegion(canvas,paint,tiles[tileIndex], tx, ty, tw, th,
	                                    transform, dx, dy, 20);
	                        }
	                    } else {
	                        tileIndex = frameData[frameIndex][0 + offset];
	                        dx = frameData[frameIndex][1 + offset] + x;
	                        dy = frameData[frameIndex][2 + offset] + y;
	                        transform = frameData[frameIndex][3 + offset];
	                        tx = tileData[tileIndex][0];
	                        ty = tileData[tileIndex][1];
	                        tw = tileData[tileIndex][2];
	                        th = tileData[tileIndex][3];

	                        if (intersectRect(dx, dy, tw, th, clipX, clipY,
	                                clipWidth, clipHeight)) {
	                        	drawRegion(canvas,paint,image,/*matrix,*/ tx, ty, tw, th, transform, dx,
										dy,20);
	                        }
	                    }
	                    offset += 4;
	                }
	            } else {
	                // render transform action
	                int tileIndex; // tile index
	                int dx; // tile dest x
	                int dy; // tile dest y
	                int transform; // tile transform
	                int tx; // tile x
	                int ty; // tile y
	                int tw; // tile width
	                int th; // tile height
	                int cx;
	                int cy;
	                int frameIndex = getSequenceFrame();
	                int tileCount = frameData[frameIndex][FRAME_TILE_COUNT_BIT];
	                int offset = FRAME_HEADER_SIZE; // tile data offset
	                for (int i = 0; i < tileCount; i++) {
	                    if (tileMode) {
	                        tileIndex = frameData[frameIndex][0 + offset];
	                        dx = frameData[frameIndex][1 + offset] + x;
	                        dy = frameData[frameIndex][2 + offset] + y;
	                        transform = frameData[frameIndex][3 + offset];
	                        tx = 0;
	                        ty = 0;
	                        tw = tiles[tileIndex].getWidth();
	                        th = tiles[tileIndex].getHeight();

	                        cx = x - dx;
	                        cy = y - dy;
	                        // finally transform
	                        transform = TRANSFORM_TABLE[transform][actionTransform];
	                        // adjust coordinate
	                        switch (actionTransform) {
	                        case TRANS_NONE:

	                            // null
	                            break;
	                        case TRANS_ROT90:

	                            dx = x - (th - cy);
	                            dy = y - cx;
	                            break;
	                        case TRANS_ROT180:

	                            dx = x - (tw - cx);
	                            dy = y - (th - cy);
	                            break;
	                        case TRANS_ROT270:

	                            dx = x - cy;
	                            dy = y - (tw - cx);
	                            break;
	                        case TRANS_MIRROR:

	                            dx = x - (tw - cx);
	                            break;
	                        case TRANS_MIRROR_ROT90:

	                            dx = x - (th - cy);
	                            dy = y - (tw - cx);
	                            break;
	                        case TRANS_MIRROR_ROT180:

	                            dy = y - (th - cy);
	                            break;
	                        case TRANS_MIRROR_ROT270:

	                            dx = x - cy;
	                            dy = y - cx;
	                            break;
	                        }
	                        if (intersectRect(dx, dy, tw, th, clipX, clipY,
	                                clipWidth, clipHeight)) {
	                            drawRegion(canvas,paint,tiles[tileIndex], tx, ty, tw, th,
	                                    transform, dx, dy, 20);
	                        }
	                        offset += 4;
	                    } else {
	                        tileIndex = frameData[frameIndex][0 + offset];
	                        dx = frameData[frameIndex][1 + offset] + x;
	                        dy = frameData[frameIndex][2 + offset] + y;
	                        transform = frameData[frameIndex][3 + offset];
	                        tx = tileData[tileIndex][0];
	                        ty = tileData[tileIndex][1];
	                        tw = tileData[tileIndex][2];
	                        th = tileData[tileIndex][3];

	                        cx = x - dx;
	                        cy = y - dy;
	                        // finally transform
	                        transform = TRANSFORM_TABLE[transform][actionTransform];
	                        // adjust coordinate
	                        switch (actionTransform) {
	                        case TRANS_NONE:

	                            // null
	                            break;
	                        case TRANS_ROT90:

	                            dx = x - (th - cy);
	                            dy = y - cx;
	                            break;
	                        case TRANS_ROT180:

	                            dx = x - (tw - cx);
	                            dy = y - (th - cy);
	                            break;
	                        case TRANS_ROT270:

	                            dx = x - cy;
	                            dy = y - (tw - cx);
	                            break;
	                        case TRANS_MIRROR:

	                            dx = x - (tw - cx);
	                            break;
	                        case TRANS_MIRROR_ROT90:

	                            dx = x - (th - cy);
	                            dy = y - (tw - cx);
	                            break;
	                        case TRANS_MIRROR_ROT180:

	                            dy = y - (th - cy);
	                            break;
	                        case TRANS_MIRROR_ROT270:

	                            dx = x - cy;
	                            dy = y - cx;
	                            break;
	                        }
	                        if (intersectRect(dx, dy, tw, th, clipX, clipY,
	                                clipWidth, clipHeight)) {
	                        	drawRegion(canvas,paint,image,/*matrix,*/ tx, ty, tw, th, transform, dx,
										dy,20);
	                        }
	                        offset += 4;
	                    }
	                }
	            }
	        }
	    }

//	    public static void drawRegionMIDP1(Graphics g, Image src, int x_src,
//	            int y_src, int width, int height, int transform, int x_dest,
//	            int y_dest, int anchor) {
//	        // insure object not null
//	        if (g == null || src == null) {
//	            throw new NullPointerException();
//	        }
//	        // check anchor validity
//	        if (!checkAnchor(anchor, Graphics.BASELINE)) {
//	            throw new IllegalArgumentException();
//	        }
//	        // check transform validity
//	        if (transform < 0 || transform > 7) {
//	            throw new IllegalArgumentException();
//	        }
//	        // insure clip rect in image bound
//	        if (width < 0 || height < 0 || x_src < 0 || y_src < 0
//	                || x_src + width > src.getWidth()
//	                || y_src + height > src.getHeight()) {
//	            throw new IllegalArgumentException();
//	        }
//	        // save graphics old clip bound
//	        int clipX = g.getClipX();
//	        int clipY = g.getClipY();
//	        int clipWidth = g.getClipWidth();
//	        int clipHeight = g.getClipHeight();
//
//	        // if inverted axes width and height is change for
//	        if ((INVERTED_AXES & transform) != 0) {
//	            if (anchor != 0) {
//	                // bottom
//	                if ((anchor & Graphics.BOTTOM) != 0) {
//	                    y_dest -= width;
//	                }
//	                // right
//	                if ((anchor & Graphics.RIGHT) != 0) {
//	                    x_dest -= height;
//	                }
//	                // horizontal
//	                if ((anchor & Graphics.HCENTER) != 0) {
//	                    x_dest -= height / 2;
//	                }
//	                // vertical
//	                if ((anchor & Graphics.VCENTER) != 0) {
//	                    y_dest -= width / 2;
//	                }
//	            }
//	            // clip
//	            g.clipRect(x_dest, y_dest, height, width);
//	        } else {
//	            if (anchor != 0) {
//	                // bottom
//	                if ((anchor & Graphics.BOTTOM) != 0) {
//	                    y_dest -= height;
//	                }
//	                // right
//	                if ((anchor & Graphics.RIGHT) != 0) {
//	                    x_dest -= width;
//	                }
//	                // horizontal
//	                if ((anchor & Graphics.HCENTER) != 0) {
//	                    x_dest -= width / 2;
//	                }
//	                // vertical
//	                if ((anchor & Graphics.VCENTER) != 0) {
//	                    y_dest -= height / 2;
//	                }
//	            }
//	            // clip
//	            g.clipRect(x_dest, y_dest, width, height);
//	        }
//
//	        // x offset
//	        int x_offset = 0;
//	        // y offset
//	        int y_offset = 0;
//
//	        // image width
//	        int srcWidth = src.getWidth();
//	        // image height
//	        int srcHeight = src.getHeight();
//
//	        switch (transform) {
//	        case TRANS_NONE:
//	            g.drawImage(src, x_dest - x_src, y_dest - y_src, Graphics.LEFT | Graphics.TOP);
//	            g.setClip(clipX, clipY, clipWidth, clipHeight);
//	            return;
//	        case TRANS_ROT90:
//	            x_offset = srcHeight - (y_src + height);
//	            y_offset = x_src;
//	            break;
//	        case TRANS_ROT180:
//	            x_offset = srcWidth - (x_src + width);
//	            y_offset = srcHeight - (y_src + height);
//	            break;
//	        case TRANS_ROT270:
//	            x_offset = y_src;
//	            y_offset = srcWidth - (x_src + width);
//	            break;
//	        case TRANS_MIRROR:
//	            x_offset = srcWidth - (x_src + width);
//	            y_offset = y_src;
//	            break;
//	        case TRANS_MIRROR_ROT90:
//	            x_offset = srcHeight - (y_src + height);
//	            y_offset = srcWidth - (x_src + width);
//	            break;
//	        case TRANS_MIRROR_ROT180:
//	            x_offset = x_src;
//	            y_offset = srcHeight - (y_src + height);
//	            break;
//	        case TRANS_MIRROR_ROT270:
//	            x_offset = y_src;
//	            y_offset = x_src;
//	            break;
//	        }
//
//	        x_dest -= x_offset;
//	        y_dest -= y_offset;
//
//	        int clipX1 = g.getClipX();
//	        int clipY1 = g.getClipY();
//	        int clipX2 = g.getClipX() + g.getClipWidth();
//	        int clipY2 = g.getClipY() + g.getClipHeight();
//
//	        if ((INVERTED_AXES & transform) != 0) {
//	            int temp = srcWidth;
//	            srcWidth = srcHeight;
//	            srcHeight = temp;
//	        }
//
//	        int src_start_x = Math.max(0, clipX1 - x_dest);
//	        int src_start_y = Math.max(0, clipY1 - y_dest);
//
//	        int dest_start_x = Math.max(clipX1, x_dest);
//	        int dest_start_y = Math.max(clipY1, y_dest);
//
//	        int dest_right = x_dest + srcWidth;
//	        int dest_bottom = y_dest + srcHeight;
//
//	        int copy_width = srcWidth - src_start_x;
//	        int copy_height = srcHeight - src_start_y;
//
//	        copy_width -= Math.max(0, dest_right - clipX2);
//	        copy_height -= Math.max(0, dest_bottom - clipY2);
//
//	        int px = 0;
//	        int py = 0;
//
//	        for (int i = 0; i < copy_height; i++) {
//	            for (int j = 0; j < copy_width; j++) {
//	                switch (transform) {
//	                case TRANS_ROT90:
//	                    px = src_start_y + i;
//	                    py = (srcWidth - 1 - j) - src_start_x;
//	                    break;
//	                case TRANS_ROT180:
//	                    px = (srcWidth - 1 - j) - src_start_x;
//	                    py = (srcHeight - 1 - i) - src_start_y;
//	                    break;
//	                case TRANS_ROT270:
//	                    px = (srcHeight - 1 - i) - src_start_y;
//	                    py = src_start_x + j;
//	                    break;
//	                case TRANS_MIRROR:
//	                    px = (srcWidth - 1 - j) - src_start_x;
//	                    py = src_start_y + i;
//	                    break;
//	                case TRANS_MIRROR_ROT90:
//	                    px = (srcHeight - 1 - i) - src_start_y;
//	                    py = (srcWidth - 1 - j) - src_start_x;
//	                    break;
//	                case TRANS_MIRROR_ROT180:
//	                    px = src_start_x + j;
//	                    py = (srcHeight - 1 - i) - src_start_y;
//	                    break;
//	                case TRANS_MIRROR_ROT270:
//	                    px = src_start_y + i;
//	                    py = src_start_x + j;
//	                    break;
//	                }
//
//	                g.setClip(dest_start_x + j, dest_start_y + i, 1, 1);
//	                g.drawImage(src, dest_start_x + j - px, dest_start_y + i - py,
//	                        Graphics.LEFT | Graphics.TOP);
//	            }
//	        }
//
//	        g.setClip(clipX, clipY, clipWidth, clipHeight);
//	    }

	    // public static void drawRegionNokia(KGraphics g, KImage src, int x_src,
	    // int y_src,
	    // int width, int height, int transform,
	    // int x_dest,
	    // int y_dest, int anchor)
	    // {
	    // //insure object not null
	    // if(g == null || src == null)
	    // {
	    // throw new NullPointerException();
	    // }
	    // //check anchor validity
	    // if(!checkAnchor(anchor, KGraphics.BASELINE))
	    // {
	    // throw new IllegalArgumentException();
	    // }
	    // //check transform validity
	    // if(transform < 0 || transform > 7)
	    // {
	    // throw new IllegalArgumentException();
	    // }
	    // //insure clip rect in image bound
	    // if(width < 0 || height < 0 || x_src < 0 || y_src < 0 ||
	    // x_src + width > src.getWidth() || y_src + height > src.getHeight())
	    // {
	    // throw new IllegalArgumentException();
	    // }
	    // //save graphics old clip bound
	    // int clipX = g.getClipX();
	    // int clipY = g.getClipY();
	    // int clipWidth = g.getClipWidth();
	    // int clipHeight = g.getClipHeight();
	    //
	    // //if inverted axes width and height is change for
	    // if((INVERTED_AXES & transform) != 0)
	    // {
	    // if(anchor != 0)
	    // {
	    // //bottom
	    // if((anchor & g.BOTTOM) != 0)
	    // {
	    // y_dest -= width;
	    // }
	    // //right
	    // if((anchor & g.RIGHT) != 0)
	    // {
	    // x_dest -= height;
	    // }
	    // //horizontal
	    // if((anchor & g.HCENTER) != 0)
	    // {
	    // x_dest -= height / 2;
	    // }
	    // //vertical
	    // if((anchor & g.VCENTER) != 0)
	    // {
	    // y_dest -= width / 2;
	    // }
	    // }
	    // //clip
	    // g.clipRect(x_dest, y_dest, height, width);
	    // }
	    // else
	    // {
	    // if(anchor != 0)
	    // {
	    // //bottom
	    // if((anchor & g.BOTTOM) != 0)
	    // {
	    // y_dest -= height;
	    // }
	    // //right
	    // if((anchor & g.RIGHT) != 0)
	    // {
	    // x_dest -= width;
	    // }
	    // //horizontal
	    // if((anchor & g.HCENTER) != 0)
	    // {
	    // x_dest -= width / 2;
	    // }
	    // //vertical
	    // if((anchor & g.VCENTER) != 0)
	    // {
	    // y_dest -= height / 2;
	    // }
	    // }
	    // //clip
	    // g.clipRect(x_dest, y_dest, width, height);
	    // }
	    //
	    // //nokia transform value
	    // int manipulation = 0;
	    // //x offset
	    // int x_offset = 0;
	    // //y offset
	    // int y_offset = 0;
	    //
	    // switch(transform)
	    // {
	    // case TRANS_NONE:
	    //
	    // //transform is none use KGraphics#drawKImage
	    // g.drawKImage(src, x_dest - x_src, y_dest - y_src, 0);
	    //
	    // //resume graphics old clip
	    // g.setClip(clipX, clipY, clipWidth, clipHeight);
	    //
	    // //return
	    // return;
	    // case TRANS_ROT90:
	    // manipulation = com.nokia.mid.ui.DirectGraphics.ROTATE_270;
	    // x_offset = src.getHeight() - (y_src + height);
	    // y_offset = x_src;
	    // break;
	    // case TRANS_ROT180:
	    // manipulation = com.nokia.mid.ui.DirecKGraphics.ROTATE_180;
	    // x_offset = src.getWidth() - (x_src + width);
	    // y_offset = src.getHeight() - (y_src + height);
	    // break;
	    // case TRANS_ROT270:
	    // manipulation = com.nokia.mid.ui.DirectGraphics.ROTATE_90;
	    // x_offset = y_src;
	    // y_offset = src.getWidth() - (x_src + width);
	    // break;
	    // case TRANS_MIRROR:
	    // manipulation = com.nokia.mid.ui.DirectGraphics.FLIP_HORIZONTAL;
	    // x_offset = src.getWidth() - (x_src + width);
	    // y_offset = y_src;
	    // break;
	    // case TRANS_MIRROR_ROT90:
	    // manipulation = com.nokia.mid.ui.DirectGraphics.FLIP_HORIZONTAL |
	    // com.nokia.mid.ui.DirectGraphics.ROTATE_90;
	    // x_offset = src.getHeight() - (y_src + height);
	    // y_offset = src.getWidth() - (x_src + width);
	    // break;
	    // case TRANS_MIRROR_ROT180:
	    // manipulation = com.nokia.mid.ui.DirectGraphics.FLIP_HORIZONTAL |
	    // com.nokia.mid.ui.DirectGraphics.ROTATE_180;
	    // x_offset = x_src;
	    // y_offset = src.getHeight() - (y_src + height);
	    // break;
	    // case TRANS_MIRROR_ROT270:
	    // manipulation = com.nokia.mid.ui.DirectGraphics.FLIP_HORIZONTAL |
	    // com.nokia.mid.ui.DirectGraphics.ROTATE_270;
	    // x_offset = y_src;
	    // y_offset = x_src;
	    // break;
	    // }
	    // //draw transform image
	    // com.nokia.mid.ui.DirectGraphics dg =
	    // com.nokia.mid.ui.DirectUtils.getDirectGraphics(g);
	    // dg.drawKImage(src, x_dest - x_offset, y_dest - y_offset, 0,
	    // manipulation);
	    // //resume graphics old clip
	    // g.setClip(clipX, clipY, clipWidth, clipHeight);
	    // }

//	    public static boolean checkAnchor(int anchor, int illegal_vpos) {
//	        boolean right;
//
//	        if (anchor == 0) {
//	            return true; /* special case: 0 is ok */
//	        }
//
//	        right = (anchor > 0) && (anchor < (Graphics.BASELINE << 1))
//	                && ((anchor & illegal_vpos) == 0);
//
//	        if (right) {
//	            int n = anchor
//	                    & (Graphics.TOP | Graphics.BOTTOM | Graphics.BASELINE | Graphics.VCENTER);
//	            right = (n != 0) && ((n & (n - 1)) == 0); /* exactly one bit set */
//	        }
//
//	        if (right) {
//	            int n = anchor
//	                    & (Graphics.LEFT | Graphics.RIGHT | Graphics.HCENTER);
//	            right = (n != 0) && ((n & (n - 1)) == 0); /* exactly one bit set */
//	        }
//
//	        return right;
//	    }
//
//	    public boolean actOver() {
//	        if ((sequenceIndex+1) == getSequenceLength()) {
//	            return true;
//	        } else {
//	            return false;
//	        }
//	    }

//	    public static void drawRegion(Canvas canvas, Paint paint, Bitmap bitmap,
//				/*Matrix matrix,*/int imgX,int imgY,int imgW,int imgH,int transform ,int screenX,
//				int screenY ,int athor ) {
////			Matrix matrix = null;
////			matrix = new Matrix();
//			// MIDP2.0
////			UtilsBitmap.drawRegion(/*canvas, paint,*/ bitmap,/* matrix,*/ imgX, imgY,
////					imgW, imgH, transform, screenX, screenY,athor);
//			
//			drawRegoin(canvas,paint,bitmap,transform,screenX, screenY,imgX, imgY,imgW, imgH);
//			// //MIDP1.0
//			// drawRegionMIDP1(g, src, x_src, y_src, width, height, transform,
//			// x_dest,
//			// y_dest,
//			// anchor);
//			// MIDP nokia
//			// drawRegionNokia(g, src, x_src, y_src, width, height, transform,
//			// x_dest,
//			// y_dest, anchor);
//		}
		//	    public static void drawRegion(Canvas canvas, Paint paint, Bitmap bitmap,
		//				 int imgX,int imgY,int imgW,int imgH,int transform ,int screenX,
		//				 int screenY) {
		//			 Matrix matrix = null;
		//			 matrix = new Matrix();
		//			 // MIDP2.0
		//			 UtilsBitmap.drawRegion(canvas, paint, bitmap, matrix, imgX, imgY,
		//					 imgW, imgH, transform, screenX, screenY);
		//			 // //MIDP1.0
		//			 // drawRegionMIDP1(g, src, x_src, y_src, width, height, transform,
		//			 // x_dest,
		//			 // y_dest,
		//			 // anchor);
		//			 // MIDP nokia
		//			 // drawRegionNokia(g, src, x_src, y_src, width, height, transform,
		//			 // x_dest,
		//			 // y_dest, anchor);
		//		 }
	    
//		/**
//		 * 
//		 * @param canvas 画布
//		 * @param paint  画笔
//		 * @param bitmap 原始图片
//		 * @param trans  翻转参数  0 不翻转  1 水平翻转 2 垂直翻转
//		 * @param scrx   图片画到画布上的坐标x
//		 * @param scry   图片画到画布上的坐标y
//		 * @param resx   图片上切片原点x
//		 * @param resy   图片上切片原点y
//		 * @param w      图片上切片宽
//		 * @param h      图片上切片高
//		 */
//		public static void drawRegoin(Canvas canvas,Paint paint,Bitmap bitmap,int trans,int scrx,int scry,int resx,int resy,int w,int h)
//		{
//			float transx = 1f;
//			float transy = 1f;
//			if(trans==1)
//			{
//				transx = -1f;
//				transy =  1f;
//				resx = bitmap.getWidth()-resx-w;
//				
//			}else if(trans==2){
//				transx =  1f;
//				transy = -1f;
//				resy = bitmap.getHeight()-resy- h;
//			}
//			Matrix matrix = new Matrix();
//			matrix.postScale(transx, transy, transx==-1f?bitmap.getWidth()/2:0, transy==-1f?bitmap.getHeight()/2:0);
//			canvas.save();
//			canvas.clipRect(scrx, scry, scrx+w, scry+h);
//			
//			matrix.postTranslate((float)scrx-resx, (float)scry-resy);
//			canvas.drawBitmap(bitmap, matrix, paint);
//			canvas.restore();
//			
//		}
	    private  int flag = -1;
		private  int hueColor = -1;
		private  int saturation = -1;
		private  int f = -1;
		public  void drawRegion(Canvas canvas,Paint paint,Bitmap src,int x_src, int y_src, int width, int height,
				int transform, int x_dst, int y_dst, int anchor) {
//			if (x_src + width > src.getWidth() || y_src + height > src.getHeight() || width < 0 || height < 0 || x_src < 0 || y_src < 0)
//				throw new IllegalArgumentException("Area out of bitmap");
//			if (src == null)
//				throw new NullPointerException();
//			GameSurfaceView.matrix.reset();
			Matrix matrix = new Matrix();
			int dW = width, dH = height;
			int x_offset = 0, y_offset = 0;
			switch (transform) {
				case Animation.TRANS_NONE: {
					x_offset = -x_src;
					y_offset = -y_src;
					break;
				}
				case Animation.TRANS_ROT90: {
					matrix.preRotate(90);
					dW = height;
					dH = width;
					x_offset = dW + y_src;
					y_offset = -x_src;
					break;
				}
				case Animation.TRANS_ROT180: {
					matrix.preRotate(180);
					x_offset = dW + x_src;
					y_offset = dH + y_src;
					break;
				}
				case Animation.TRANS_ROT270: {
					matrix.preRotate(270);
					dW = height;
					dH = width;
					x_offset = -y_src;
					y_offset = dH + x_src;
					break;
				}
				case Animation.TRANS_MIRROR: {
					matrix.preScale(-1, 1);
					x_offset = dW + x_src;
					y_offset = -y_src;
					break;
				}
				case Animation.TRANS_MIRROR_ROT90: {
					matrix.preScale(-1, 1);
					matrix.preRotate(-90);
					dW = height;
					dH = width;
					x_offset = dW + y_src;
					y_offset = dH + x_src;
					break;
				}
				case Animation.TRANS_MIRROR_ROT180: {
					matrix.preScale(-1, 1);
					matrix.preRotate(-180);
					x_offset = -x_src;
					y_offset = dH + y_src;
					break;
				}
				case Animation.TRANS_MIRROR_ROT270: {
					matrix.preScale(-1, 1);
					matrix.preRotate(-270);
					dW = height;
					dH = width;
					x_offset = -y_src;
					y_offset = -x_src;
					break;
				}
				default:
					throw new IllegalArgumentException("Bad transform");
			}
			boolean badAnchor = false;
			if (anchor == 0) {
				anchor = TOP | LEFT;
			}

			if ((anchor & BASELINE) != 0)
				badAnchor = true;

			if ((anchor & TOP) != 0) {
				if ((anchor & (VCENTER | BOTTOM)) != 0)
					badAnchor = true;
			} else if ((anchor & BOTTOM) != 0) {
				if ((anchor & VCENTER) != 0)
					badAnchor = true;
				else {
					y_dst -= dH - 1;
				}
			} else if ((anchor & VCENTER) != 0) {
				y_dst -= (dH - 1) >>> 1;
			} else {
				badAnchor = true;
			}
			if ((anchor & LEFT) != 0) {
				if ((anchor & (HCENTER | RIGHT)) != 0)
					badAnchor = true;
			} else if ((anchor & RIGHT) != 0) {
				if ((anchor & HCENTER) != 0)
					badAnchor = true;
				else {
					x_dst -= dW - 1;
				}
			} else if ((anchor & HCENTER) != 0) {
				x_dst -= (dW - 1) >>> 1;
			} else {
				badAnchor = true;
			}

			if (badAnchor) {
				throw new IllegalArgumentException("Bad Anchor");
			}
			canvas.save();
			canvas.clipRect(x_dst, y_dst, x_dst + dW, y_dst + dH);
			canvas.translate(x_dst + x_offset, y_dst + y_offset);
			canvas.drawBitmap(src, matrix, paint);
			canvas.restore();
		}
		public void setListener(AnimationListener listener) {
			this.listener = listener;
		}

		public AnimationListener getListener() {
			return listener;
		}
	
}
